package com.ainge.jwt.jwe.jose4j;

import org.jose4j.jwa.AlgorithmConstraints;
import org.jose4j.jwe.ContentEncryptionAlgorithmIdentifiers;
import org.jose4j.jwe.JsonWebEncryption;
import org.jose4j.jwe.KeyManagementAlgorithmIdentifiers;
import org.jose4j.lang.JoseException;
import sun.misc.BASE64Decoder;

import java.io.IOException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;

/**
 * Created by Ainge on 2019/11/24
 */
public class Jose4JTest {


    public static PrivateKey getRsaPrivateKey(String privateKey) {
        byte[] key;
        try {
            key = new BASE64Decoder().decodeBuffer(privateKey);
        } catch (IOException e) {
            throw new RuntimeException("私钥文件BASE64解码失败_IOException：" + e.getMessage());
        }
        // 取得私钥
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key);
        // 生成私钥
        try {
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            return keyFactory.generatePrivate(pkcs8KeySpec);
        } catch (InvalidKeySpecException e) {
            throw new RuntimeException("构造生成密钥错误: " + e.getMessage());
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("NoSuchAlgorithmException: " + e.getMessage());
        }
    }


    public static String getPlaintextString(String privateKey, String compactSerialization) {

        // 1.创建JWE解密对象
        JsonWebEncryption receiverJwe = new JsonWebEncryption();
        // 2.设置RSA解密用的算法RSA_OAEP
        //AlgorithmConstraints algConstraints = new AlgorithmConstraints(AlgorithmConstraints.ConstraintType.WHITELIST, KeyManagementAlgorithmIdentifiers.RSA_OAEP);
        //receiverJwe.setAlgorithmConstraints(algConstraints);
        // 3.设置解开AES解密用的算法AES_256_GCM
        //AlgorithmConstraints encConstraints = new AlgorithmConstraints(AlgorithmConstraints.ConstraintType.WHITELIST, ContentEncryptionAlgorithmIdentifiers.AES_256_GCM);
        //receiverJwe.setContentEncryptionAlgorithmConstraints(encConstraints);
        // 4.将jwe compact内容丢进去
        try {
            receiverJwe.setCompactSerialization(compactSerialization);
        } catch (JoseException e) {
            throw new RuntimeException("setCompactSerialization exception: " + e.getMessage());
        }
        // 5. 设置私钥key进行解密
        try {
            receiverJwe.setKey(getRsaPrivateKey(privateKey));
            // 6.解密并且返回真正的数据明文(UTF-8编码)
            return receiverJwe.getPlaintextString();
        } catch (JoseException e) {
            throw new RuntimeException("JWE解密失败：" + e.getMessage(), e);
        }
    }


    public static void main(String[] args) throws JoseException {

        // 与公钥加密对应的私钥(特别注意一定要是PKCS8格式的)
        String privateKey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDEdHIR1TwwSR4m\n" +
                "pzHuK5yVUT2KuWywRAMcRshDn4DSo2DESY+T6UJj2GVVTetF9NcqFtzcknY2g6Ho\n" +
                "A2nJ3tx9YJ9UbfSLKA2tW9hlCYN98ByEZvJl/v6L2k4AIe7TW6li6TVfcbpCia66\n" +
                "qX7UfVMFqIGGwMJNiBLpjDNo5hjC7S6+2FNrYAhc17Kal6NKhyr46Kbsqrt2cvkD\n" +
                "/ZmWl8zjyZGGkycaKMnTo1GsQrrteoP8wuNq/s9IC/2XfYnP5moSVdekgLOIfYYj\n" +
                "3K413LG567mQj3c+ELWm/zuAplnP3pS/g3dsD1aUzxy5WvPhNAxoAY4M9YqHZ4o4\n" +
                "9pMek2rfAgMBAAECggEAZyUgUv6a+Fsban30ODFLqBYccr6CM1WyMGF1ehO/xlgj\n" +
                "UUuyB527zsJqCcy8T2GKqr2QPnrjeCHKmw9Xtra9G1LktKZ6c6mW7MNBLWM+V5v+\n" +
                "zQFkGWs1aGY499bZFr2UhKse67rBaXfydmzRe21Fbr4XK5H/MkfUbiy/PT86FvUW\n" +
                "9w6QDoGiCuLylxA5ncTyHGPNzFTNlSJahnfyDbkFXc4gACxwyZsYX0OICqh4KmPw\n" +
                "OkIMKtj8PJP+nz2HCe4uWLn5F/xo9ZLPQV8DM0yCevUH1aakr12Db0httEv+xI8A\n" +
                "4rBhp7ZXdOhDtuvTbRJ0fsu0M9RT6qaqwVxtCqntOQKBgQDslmo81mSS/0Z/sRfs\n" +
                "C5+2m6yx9OmPBSo87Sm4cbc3ZJ2/Z/8d9TGIoT2Cu/L6e84gtXVklWdKVWtSIDdK\n" +
                "O4SE2Om/z+reh6FUnRW7ei+MPv4WMPKTSA5O+e+mBhuiOaB0m8F4yYxAO+Vv8ere\n" +
                "Y4/pTgyqe8kj3WW7j7krYixNewKBgQDUkwhanpUBuwFQmOdXYAHvILI+IYKmMnoS\n" +
                "QnOpoT/w0MiLRFUhrGckyeHrMbCPq0PWaORSWC0VUpIuyyS41uDzwzjRi7zCEaOM\n" +
                "F1j5fHn4CKHseRdMACu7NbfeDpz/HC9mDgnoBEt80L37rY7LF6fcO/4jAr1icDlu\n" +
                "tzuleqgQ7QKBgQDkaTOYGMRwxtQhY7Bcy7weaJ2KEZGL6sikmbO1xtPEPvetW5IK\n" +
                "MjboWgMwvJQREIYpPgdgXH2kXmOGnmPC30NJnsHN1cZDoV44epAIuCY/mHFmq0sG\n" +
                "toJZ7SNZfnwfWtN2wQlAvBUTzr/sG/tNSYIfFKNV1LyUS6N0OYXkRJvREQKBgF8f\n" +
                "BCf4ulix4567LRoOHg9xJBFlUV8pSzKMhdEsFL6fzn1zMF0HFoiBxhRGgeloC80P\n" +
                "1st6JYJbForV4DLOBI9Plkc+LlLxLavsbqYFK1bwFfUJIoGhue/l08cL5vjJFfSm\n" +
                "54vpEBZkGf9a5IDArx5/wfLMsQ4xhaGjYI9l2XrpAoGAU3KA6CEPbwlzz6bgqmZ0\n" +
                "dh1KLNICFjex8GiKvnHvQVi7oeGafkjFdpkOdXrRff7N7yWlCtbV9H8BOzRg+sN7\n" +
                "wCMsysoMNkvvl02aqdPhfvu70UxMJJ8WaLvT2USBZAjLcEM9qwjfpmLOnPXF8wxX\n" +
                "usZa+XBtnS3Iepa0gMYGfts=";

        String data = "eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZHQ00ifQ.Sqnrf_rcUpqlSALdRRuvj_aOeROYSK7UOcIj9BQnCPZ7ACwP1FCDh2vKn31PFU1e-hHKEP3XjagK644UrumgWeSlx1wBElLpQEdr9MFcj-Ky9_9UQmeLdKaUNubn-uf1klw9MOj-ZkAR5VemHDlSzwJgV6Xxjmw3L1PaAeqIn69hwDa1zH917Tz0F8E3L_C7T1hlNIjoQ8wGC7fso-qKrP7UhikpHQRoTl76XXdXA4Tck5cfB3gu_qYxF6Wsadj6aXyIM6XI2rM2G-C22-_tpXiUxkqqmUu6kBQBlT2sPVJZF1zDgBUtIX7JC8OfOBKSQqvvYjxEugEr6YHy7qZKSw.eKSb0UtKKGyOQsJa.dG8Umob5y3tLbpHtGagSOQ9cPJ4KOPP4B_sGCEL7D8dj8OKnjKhIbfWWJGyyKPkFftVXaLlOFXANDHyGY3_t7TOKuTCBMsiRrJePqNT1VK3e1ktcRbsazJt2i-nPkPah6t4vadBfCX7xzVc.1BYgChg1J6fkDGiKqE6P-g";
        // jose4j 是一个不错的JWT库
        String plaintextString = getPlaintextString(privateKey, data);
        System.out.println(plaintextString);

    }


}
